package com.link2room.soundwave.facade.impl;

import com.greencloud.api.dto.OrderInfoDto;
import com.greencloud.api.dto.OrderItemDto;
import com.greencloud.api.request.*;
import com.greencloud.api.request.membercard.GetCardBalanceInfoRequest;
import com.greencloud.api.response.BookResponse;
import com.greencloud.api.response.ListBillInfoResponse;
import com.greencloud.api.response.OrderInfoResponse;
import com.greencloud.api.response.PmsResponse;
import com.greencloud.api.response.membercard.GetCardBalanceInfoResponse;

import com.link2room.bumblebee.dto.param.base.PmsReservationOptionParamDto;
import com.link2room.bumblebee.dto.param.base.SysNoBaseParamDto;
import com.link2room.bumblebee.dto.result.base.PmsReservationOptionDto;
import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.param.base.BaseParamDto;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.exception.SysException;
import com.link2room.common.jpa.condition.ConditionDetail;
import com.link2room.common.jpa.condition.L2RCondition;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.*;

import com.link2room.enums.exception.SoundwaveSysExceptionEnum;
import com.link2room.jetfire.constant.ReservationConstant;
import com.link2room.jetfire.dto.param.base.ReservationParamDto;
import com.link2room.jetfire.dto.param.inside.ReservationBaseInsideParamDto;

import com.link2room.jetfire.dto.result.base.GcOrderCouponDto;
import com.link2room.jetfire.dto.result.base.ReservationBaseDto;
import com.link2room.jetfire.dto.result.base.ReservationPriceDto;
import com.link2room.optimus.constant.BaseRateplanConstant;
import com.link2room.rodimus.dto.param.inside.SalesmanInComeDetailInsideParamDto;
import com.link2room.soundwave.constant.L2RAccountConstant;
import com.link2room.soundwave.constant.SoundwaveConstant;
import com.link2room.soundwave.constant.SoundwaveMnsConstant;
import com.link2room.soundwave.constant.SoundwaveTaskNameConstant;
import com.link2room.soundwave.dto.param.api.MemeberCardPayApiParamDto;
import com.link2room.soundwave.dto.param.base.PmsReservationBaseParamDto;
import com.link2room.soundwave.dto.param.inside.MemeberCardPayInsideParamDto;
import com.link2room.soundwave.dto.param.inside.PmsReservationPayInsideParamDto;
import com.link2room.soundwave.dto.param.inside.ReservationStaInsideParamDto;
import com.link2room.soundwave.dto.result.base.AccountResultDto;
import com.link2room.soundwave.dto.result.base.MemberCardPayDto;
import com.link2room.soundwave.dto.result.base.PmsAccountDto;
import com.link2room.soundwave.entity.*;
import com.link2room.soundwave.exception.SoundwaveException;
import com.link2room.soundwave.feign.aeriabots.WxOfiiceialAccountsInfoFeignService;
import com.link2room.soundwave.feign.bumblebee.PmsReservationOptionFeignService;
import com.link2room.soundwave.feign.bumblebee.SysNoFeignService;
import com.link2room.soundwave.feign.jetfire.ReservationsFeignService;
import com.link2room.soundwave.feign.rodimus.SalesAwardFeignService;
import com.link2room.soundwave.util.GcPmsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * Created by VegetaKo on 2016/9/23.
 */
@Component("gcPmsReservationHandlerFacadeService")
public class GcPmsReservationHandlerFacadeServiceImpl extends AbstractReservationHandlerFacadeServiceImpl {
    private static final Logger logger = LoggerFactory
            .getLogger(GcPmsReservationHandlerFacadeServiceImpl.class);
    @Resource
    private ICommonService commonService;
    @Autowired
    private WxOfiiceialAccountsInfoFeignService wxOfiiceialAccountsInfoFeignService;
    @Autowired
    private SalesAwardFeignService salesAwardFeignService;
    @Autowired
    private PmsReservationOptionFeignService pmsReservationOptionFeignService;

    @Autowired
    private ReservationsFeignService reservationsFeignService;

    @Autowired
    private RedisLockRegistry membercardPrepayIdLock;

    @Autowired
    private RedisLockRegistry membercardPayLock;

    @Autowired
    private SysNoFeignService sysNoFeignService;

    @Override
    public void savePMSReservation(ReservationParamDto reservationParamDto) throws Exception {
        ReservationBaseDto reservationBaseDto = reservationParamDto.getReservationBase();

        String lhotelGroupCode=reservationBaseDto.getLhotelGroupCode();
        String lhotelCode=reservationBaseDto.getLhotelCode();


        if( reservationParamDto.getOperType().equals(ReservationConstant.OPERTYPE.CREATE )){
            if(reservationParamDto.getReservationPriceDtos()==null||reservationParamDto.getReservationPriceDtos().size()==0){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.NO_PRICELIST);
            }
            String crsNo=null;
            PmsReservationOptionParamDto pmsReservationOptionParamDto=new PmsReservationOptionParamDto();
            pmsReservationOptionParamDto.setPbChannel(reservationBaseDto.getPbChannel());
            pmsReservationOptionParamDto.setResType(reservationBaseDto.getResType());
            PmsReservationOptionDto pmsReservationOptionDto= pmsReservationOptionFeignService.getPmsReservationOption(pmsReservationOptionParamDto.paramToMap()).getResultInfo();
            String l2rRmtype=reservationBaseDto.getRmtype();

            L2RIpms2Hotel querylih = new L2RIpms2Hotel();
            querylih.setLhotelGroupCode( lhotelGroupCode);
            querylih.setLhotelCode( lhotelCode);
            L2RIpms2Hotel l2RIpms2Hotel = commonService.findOneEQ(L2RIpms2Hotel.class, querylih);
            if(l2RIpms2Hotel==null){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPINGHOTEL_NOT_EXIT);
            }
            L2RIpms2Rmtype querylir = new L2RIpms2Rmtype();
            querylir.setLhotelGroupCode( lhotelGroupCode);
            querylir.setLhotelCode( lhotelCode);
            querylir.setL2RRmtype(l2rRmtype);
            L2RIpms2Rmtype l2RIpms2Rmtype = commonService.findOneEQ(L2RIpms2Rmtype.class, querylir);
            if(l2RIpms2Rmtype==null){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPINGRMTYPE_NOT_EXIT);
            }
            String rmtype=l2RIpms2Rmtype.getPmsRmtype();
            BookWithCouponRequest  bookWithCouponRequest=null;
            BookRequest  bookRequest=null;
            if(reservationParamDto.getGcOrderCoupons()!=null&&reservationParamDto.getGcOrderCoupons().size()>0){
                bookWithCouponRequest= this.reservationParamDtoToBookRequestWithCoupon(
                        lhotelGroupCode,
                        l2RIpms2Hotel.getHotelGroupId(),
                        l2RIpms2Hotel.getHotelId(),
                        rmtype,pmsReservationOptionDto,
                        reservationBaseDto,
                        reservationParamDto.getReservationPriceDtos(),
                        reservationParamDto.getGcOrderCoupons());
            }else {
                bookRequest= this.reservationParamDtoToBookRequest(
                        lhotelGroupCode,
                        l2RIpms2Hotel.getHotelGroupId(),
                        l2RIpms2Hotel.getHotelId(),
                        rmtype,pmsReservationOptionDto,
                        reservationBaseDto,
                        reservationParamDto.getReservationPriceDtos());
            }

            //PMS信息转换 PMS会员信息

            L2RIpms2Reservation queryL2R = new L2RIpms2Reservation();
            queryL2R.setLhotelGroupCode(reservationParamDto.getReservationBase().getLhotelGroupCode() );
            queryL2R.setLhotelCode( reservationParamDto.getReservationBase().getLhotelCode());
            queryL2R.setL2RNo( reservationParamDto.getReservationBase().getL2RNo());
            QueryResult<L2RIpms2Reservation> l2RIpms2ReservationResult = commonService.findAllEQ(L2RIpms2Reservation.class, queryL2R);

            if(StringUtil.isNotBlank(reservationParamDto.getReservationBase().getMemberNo() ) ){
                L2RIpms2Member l2RIpms2Member = new L2RIpms2Member();
                l2RIpms2Member.setL2RMemberNo( reservationParamDto.getReservationBase().getMemberNo());
                l2RIpms2Member.setLhotelGroupCode(lhotelGroupCode );
                l2RIpms2Member= commonService.findOneEQ(L2RIpms2Member.class,l2RIpms2Member );
                if( null!= l2RIpms2Member){
                    if(bookWithCouponRequest!=null){
                        bookWithCouponRequest.setCardNo( l2RIpms2Member.getCardNo());
                    }else if(bookRequest!=null){
                        bookRequest.setCardNo(l2RIpms2Member.getCardNo());
                    }
                    if( l2RIpms2Member.getName().equals( reservationBaseDto.getRsvMan())){
                        if(bookWithCouponRequest!=null) {
                            bookWithCouponRequest.setIdType(l2RIpms2Member.getIdType());
                            bookWithCouponRequest.setIdNo(l2RIpms2Member.getIdNo());
                        }else if(bookRequest!=null){
                            bookRequest.setIdType(l2RIpms2Member.getIdType());
                            bookRequest.setIdNo(l2RIpms2Member.getIdNo());
                        }
                    }
                }
            }
            if(l2RIpms2ReservationResult.getResultlist()==null||l2RIpms2ReservationResult.getResultlist().size()==0){
                BookResponse bookResponse=null;
                if(bookWithCouponRequest!=null) {
                    bookResponse = GcPmsUtil.getGcClient(lhotelGroupCode).execute(bookWithCouponRequest);
                }else if(bookRequest!=null){
                    bookResponse = GcPmsUtil.getGcClient(lhotelGroupCode).execute(bookRequest);
                }
                if(bookResponse.getResultCode()<0){
                    throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_SAVE_ERROR,bookResponse.getResultMsg());
                }else {
                    L2RIpms2Reservation l2RIpms2Reservation = new L2RIpms2Reservation();
                    l2RIpms2Reservation.setLhotelGroupCode(reservationParamDto.getReservationBase().getLhotelGroupCode() );
                    l2RIpms2Reservation.setLhotelCode( reservationParamDto.getReservationBase().getLhotelCode());
                    l2RIpms2Reservation.setL2RNo( reservationParamDto.getReservationBase().getL2RNo());
                    l2RIpms2Reservation.setHotelId(String.valueOf(l2RIpms2Hotel.getHotelId() ));
                    l2RIpms2Reservation.setHotelGroupId(String.valueOf(l2RIpms2Hotel.getHotelGroupId() ) );
                    l2RIpms2Reservation.setCrsNo(bookResponse.getCrsNo());
                    l2RIpms2Reservation.setPmsSta(ReservationConstant.RESSTA.R);
                    l2RIpms2Reservation.setOpenId(reservationParamDto.getReservationBase().getOpenid());
                    l2RIpms2Reservation.setRsvMan(reservationParamDto.getReservationBase().getRsvMan());
                    l2RIpms2Reservation.setMemberNo(reservationParamDto.getReservationBase().getMemberNo());
                    commonService.save(l2RIpms2Reservation );
                    crsNo=l2RIpms2Reservation.getCrsNo();
                }
            }
            ReservationBaseInsideParamDto reservationBaseInsideParamDto = new ReservationBaseInsideParamDto();
            reservationBaseInsideParamDto.setLhotelGroupCode( reservationBaseDto.getLhotelGroupCode());
            reservationBaseInsideParamDto.setLhotelCode(reservationBaseDto.getLhotelCode() );
            reservationBaseInsideParamDto.setCrsNo( crsNo );
            reservationBaseInsideParamDto.setL2RNo( reservationBaseDto.getL2RNo());
            reservationsFeignService.updateReservationSta(reservationBaseInsideParamDto);
        } else{
            this.cancelPMSReservation(reservationParamDto);
        }
    }

    @Override
    public void cancelPMSReservation(ReservationParamDto reservationParamDto) throws Exception {
        L2RIpms2Reservation queryLIR = new L2RIpms2Reservation();
        queryLIR.setLhotelGroupCode(reservationParamDto.getLhotelGroupCode());
        queryLIR.setL2RNo( reservationParamDto.getReservationBase().getL2RNo());
        L2RIpms2Reservation l2RIpms2Reservation  = commonService.findOneEQ(L2RIpms2Reservation.class, queryLIR);

        if(l2RIpms2Reservation!=null){
            CancelbookRequest cancelbookRequest=CancelbookRequest.newInstance();
            cancelbookRequest.setHotelGroupId(Long.valueOf(l2RIpms2Reservation.getHotelGroupId()));
            cancelbookRequest.setCrsNo(l2RIpms2Reservation.getCrsNo());
            cancelbookRequest.setCardNo("");
            PmsResponse pmsResponse = GcPmsUtil.getGcClient(reservationParamDto.getLhotelGroupCode()).execute(cancelbookRequest);
            if(pmsResponse.getResultCode()<0){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_CANCEL_ERROR,pmsResponse.getResultMsg());
            }else {
                l2RIpms2Reservation.setPmsSta(ReservationConstant.RESSTA.X);
                commonService.merge(l2RIpms2Reservation);
                ReservationBaseInsideParamDto reservationBaseInsideParamDto = new ReservationBaseInsideParamDto();
                reservationBaseInsideParamDto.setLhotelGroupCode( reservationParamDto.getLhotelGroupCode());
                reservationBaseInsideParamDto.setLhotelCode(l2RIpms2Reservation.getLhotelCode() );
                reservationBaseInsideParamDto.setCrsNo( l2RIpms2Reservation.getCrsNo() );
                reservationBaseInsideParamDto.setL2RNo( l2RIpms2Reservation.getL2RNo());
                reservationBaseInsideParamDto.setResSta(ReservationConstant.RESSTA.X);
                reservationsFeignService.updateReservationSta(reservationBaseInsideParamDto);
            }
        }else {
            throw new SysException(SoundwaveSysExceptionEnum.PMSRESER_NOT_EXIT);
        }
    }

    @Override
    public void savePMSReservationPay(PmsReservationPayInsideParamDto pmsReservationPayInsideParamDto) throws Exception {
        L2RIpms2Reservation queryLIR = new L2RIpms2Reservation();
        queryLIR.setL2RNo( pmsReservationPayInsideParamDto.getL2RNo());
        queryLIR.setLhotelGroupCode(pmsReservationPayInsideParamDto.getLhotelGroupCode() );
        L2RIpms2Reservation l2RIpms2Reservation  = commonService.findOneEQ(L2RIpms2Reservation.class, queryLIR);

        SaveWebPayRequest saveWebPayRequest=SaveWebPayRequest.newInstance();
        saveWebPayRequest.setHotelGroupId(Long.parseLong(l2RIpms2Reservation.getHotelGroupId()));
        saveWebPayRequest.setLimitOnce(pmsReservationPayInsideParamDto.getLimitOnce());
        if(StringUtil.isNotBlank(pmsReservationPayInsideParamDto.getTaCode())){
            saveWebPayRequest.setTaCode(pmsReservationPayInsideParamDto.getTaCode());
        }else {
            String taCode = SysoptionUtil.getSysOption(pmsReservationPayInsideParamDto.getLhotelGroupCode(), SoundwaveConstant.SAVEPAY, SoundwaveConstant.SAVEPAY_ITEM.TACODE);
            if(StringUtil.isNotBlank(taCode)){
                saveWebPayRequest.setTaCode(taCode);
            }else{
                throw new SoundwaveException(SoundwaveSysExceptionEnum.TACODE_NOT_EXIT);
            }
        }
        saveWebPayRequest.setTaNo(pmsReservationPayInsideParamDto.getTaNo() );
        saveWebPayRequest.setCrsNo( l2RIpms2Reservation.getCrsNo());
        if(StringUtil.isNotBlank(pmsReservationPayInsideParamDto.getRemark())){
            saveWebPayRequest.setTaRemark(pmsReservationPayInsideParamDto.getRemark());
        }else {
            saveWebPayRequest.setTaRemark("");
        }
        saveWebPayRequest.setMoney(pmsReservationPayInsideParamDto.getAmount());
        PmsResponse pmsResponse = GcPmsUtil.getGcClient(pmsReservationPayInsideParamDto.getLhotelGroupCode()).execute(saveWebPayRequest);
        if(pmsResponse.getResultCode()<0){
            throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_SAVE_PAY_ERROR,pmsResponse.getResultMsg());
        }
    }

    @Override
    public void syncReservationSta(ReservationStaInsideParamDto reservationStaInsideParamDto) throws Exception {
        List<String> pmsStas = new ArrayList<>();
        pmsStas.add(ReservationConstant.RESSTA.R);
        pmsStas.add(ReservationConstant.RESSTA.S);
        pmsStas.add(ReservationConstant.RESSTA.I);
        L2RCondition stockConfition=new L2RCondition();
        stockConfition.setAndConditions(new ConditionDetail[]{
                new ConditionDetail(L2RIpms2Reservation.BaseEntity_.lhotelGroupCode.toString(), CriteriaUtil.Operator.EQ, reservationStaInsideParamDto.getLhotelGroupCode() ),
                new ConditionDetail(L2RIpms2Reservation.BaseEntity_.lhotelCode.toString(), CriteriaUtil.Operator.EQ, reservationStaInsideParamDto.getLhotelCode() ),
                new ConditionDetail(L2RIpms2Reservation.L2RIpms2Reservation_.pmsSta.toString(), CriteriaUtil.Operator.IN,pmsStas)
        });
        QueryResult<L2RIpms2Reservation> l2RIpms2ReservationQueryResult = commonService.findAllByCondition(L2RIpms2Reservation.class, stockConfition);
        if(  null !=l2RIpms2ReservationQueryResult.getResultlist()&& l2RIpms2ReservationQueryResult.getResultlist().size()>0){
            List<PmsReservationBaseParamDto> pmsReservationBaseParamDtos =new ArrayList<>();

            for (L2RIpms2Reservation L2RIpms2Reservation1 : l2RIpms2ReservationQueryResult.getResultlist()) {
                PmsReservationBaseParamDto pmsReservationBaseParamDto=new PmsReservationBaseParamDto();
                pmsReservationBaseParamDto.setLhotelGroupCode(L2RIpms2Reservation1.getLhotelGroupCode());
                pmsReservationBaseParamDto.setHotelGroupId(Long.parseLong(L2RIpms2Reservation1.getHotelGroupId()));
                pmsReservationBaseParamDto.setCrsNo(L2RIpms2Reservation1.getCrsNo());
                pmsReservationBaseParamDto.setLhotelCode(L2RIpms2Reservation1.getLhotelCode());
                pmsReservationBaseParamDto.setHotelId(Long.parseLong(L2RIpms2Reservation1.getHotelId()));
                pmsReservationBaseParamDtos.add(pmsReservationBaseParamDto);
            }
            BatchUtil.beginBatchTask(SoundwaveMnsConstant.QUEUE_PMSRESSTA,
                    SoundwaveTaskNameConstant.SAVE_PMS_RESSTA,
                    pmsReservationBaseParamDtos);
        }
    }

    @Override
    public void syncPMSHotelReservationSta(PmsReservationBaseParamDto pmsReservationBaseParamDto) throws Exception {
        String lhotelGroupCode=pmsReservationBaseParamDto.getLhotelGroupCode();
        String lhotelCode=pmsReservationBaseParamDto.getLhotelCode();
        Long hotelGroupId=pmsReservationBaseParamDto.getHotelGroupId();
        Long hotelId=pmsReservationBaseParamDto.getHotelId();
        L2RAssert.stringBlank(pmsReservationBaseParamDto.getCrsNo(),"CRSNO为空");
        L2RIpms2Reservation queryLIR = new L2RIpms2Reservation();
        queryLIR.setCrsNo(pmsReservationBaseParamDto.getCrsNo() );
        //l2RIpms2Reservation.setPmsSta(pmsBookInfoDto.getSta() );
        L2RIpms2Reservation l2RIpms2Reservation = commonService.findOneEQ(L2RIpms2Reservation.class, queryLIR);
        if(l2RIpms2Reservation!=null){
            OrderInfoRequest orderInfoRequest = OrderInfoRequest.newInstance();
            orderInfoRequest.setHotelGroupId(hotelGroupId);
            orderInfoRequest.setCrsNo(pmsReservationBaseParamDto.getCrsNo());
            OrderInfoResponse orderInfoResp = GcPmsUtil.getGcClient(pmsReservationBaseParamDto.getLhotelGroupCode()).execute(orderInfoRequest);
            if(orderInfoResp.getResultCode()<0){
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_QUERY_ORDER_ERROR,orderInfoResp.getResultMsg());
            }
            OrderInfoDto orderInfoDto=orderInfoResp.getResult();
            if(orderInfoDto!=null){
                if(StringUtil.isNotBlank(orderInfoDto.getCrsNo())){
                    l2RIpms2Reservation.setPmsSta(orderInfoDto.getSta() );
                    commonService.merge(l2RIpms2Reservation );
                    //同步L2R_order库 订单
                    ReservationBaseInsideParamDto reservationBaseInsideParamDto = new ReservationBaseInsideParamDto();
                    reservationBaseInsideParamDto.setLhotelGroupCode( lhotelGroupCode);
                    reservationBaseInsideParamDto.setLhotelCode(lhotelCode );
                    reservationBaseInsideParamDto.setResSta( orderInfoDto.getSta() );
                    reservationBaseInsideParamDto.setL2RNo( l2RIpms2Reservation.getL2RNo());
                    reservationBaseInsideParamDto.setCrsNo(l2RIpms2Reservation.getCrsNo());
                    reservationsFeignService.updateReservationSta(reservationBaseInsideParamDto);
                    reservationBaseInsideParamDto.setArrtime(DateUtil.getNewFormatDateString( new Date(Long.parseLong(orderInfoDto.getArr()))));
                    reservationBaseInsideParamDto.setDeptime(DateUtil.getNewFormatDateString(new Date(Long.parseLong(orderInfoDto.getDep()))));


                    //Integer nights= this.getReservationNight(orderInfoDto);
                    //重新计算间夜，目前暂时修改离店日期以达到重算日期
                    //reservationBaseInsideParamDto.setDeptime(  DateUtil.format(DateUtil.addDays(reservationBaseInsideParamDto.getArr(), nights.longValue()),DateUtil.webFormat));
                    reservationBaseInsideParamDto.setOpenid(l2RIpms2Reservation.getOpenId());
                    reservationBaseInsideParamDto.setRsvMan(l2RIpms2Reservation.getRsvMan());
                    reservationBaseInsideParamDto.setMemberNo(l2RIpms2Reservation.getMemberNo());
                    //同步到L2R_member库 订单奖励

                    if(ReservationConstant.RESSTA.O.equals(orderInfoDto.getSta()) ){
                        // 新增一条消息处理点评
                        // 改由PMS系统发起
                        // mnsUtil.putMessageToQueue(MnsConstant.QUEUE_MSG_TO_BRANDWISDOM_GSS, JacksonUtil.beanToJson(reservationBaseInsideParamDto));
                        //奖励分销员
                        SalesmanInComeDetailInsideParamDto salesmanInComeDetailInsideParamDto=ClassConverUtil.copyProperties(reservationBaseInsideParamDto,SalesmanInComeDetailInsideParamDto.class);
                        salesmanInComeDetailInsideParamDto.setResType(reservationBaseInsideParamDto.getResType());
                        //同步登记单
                        this.saveOrUpdateMasterInfo(lhotelGroupCode,
                                lhotelCode,
                                hotelGroupId,
                                hotelId,
                                orderInfoDto,
                                l2RIpms2Reservation.getL2RNo(),
                                l2RIpms2Reservation.getCrsNo());
                        //同步账务


                        this.saveGcBillAccount(lhotelGroupCode,
                                lhotelCode,
                                l2RIpms2Reservation.getCrsNo(),
                                l2RIpms2Reservation.getL2RNo()
                        );
                        Integer nights=this.getReservationNight2(lhotelGroupCode,lhotelCode,l2RIpms2Reservation.getCrsNo());
                        salesmanInComeDetailInsideParamDto.setDeptime(  DateUtil.format(DateUtil.addDays(reservationBaseInsideParamDto.getArr(), nights.longValue()),DateUtil.webFormat));
                        salesAwardFeignService.awardSalesmanReservation(salesmanInComeDetailInsideParamDto);
                    }else if(ReservationConstant.RESSTA.I.equals(orderInfoDto.getSta())){
                        this.saveOrUpdateMasterInfo(lhotelGroupCode,
                                lhotelCode,
                                hotelGroupId,
                                hotelId,
                                orderInfoDto,
                                l2RIpms2Reservation.getL2RNo(),
                                l2RIpms2Reservation.getCrsNo());
                    }
                    BatchUtil.doBatchTaskDone(pmsReservationBaseParamDto.getTaskMainId(),
                            pmsReservationBaseParamDto.getTaskId(),
                            pmsReservationBaseParamDto.getIsBatch());

                }
            }else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_QUERY_ORDER_ERROR,orderInfoResp.getResultMsg());
            }
        }
    }



    @Override
    QueryResult<PmsAccountDto> listPmsAccounts(PmsReservationBaseParamDto pmsReservationBaseParamDto) throws Exception {
        this.saveGcBillAccount(pmsReservationBaseParamDto.getLhotelGroupCode(),
                pmsReservationBaseParamDto.getLhotelCode(),
                pmsReservationBaseParamDto.getCrsNo(),
                pmsReservationBaseParamDto.getL2rNo()
        );
        L2RIpms2Account queryIAccount=new L2RIpms2Account();
        queryIAccount.setLhotelGroupCode(pmsReservationBaseParamDto.getLhotelGroupCode());
        queryIAccount.setLhotelCode(pmsReservationBaseParamDto.getLhotelCode());
        queryIAccount.setL2RNo(pmsReservationBaseParamDto.getL2rNo());
        QueryResult<L2RIpms2Account> accountResult = commonService.findAllEQ(L2RIpms2Account.class, queryIAccount);
        return ClassConverUtil.copyQueryResultToDtoQueryResult(accountResult,PmsAccountDto.class,false);
    }

    @Override
    AccountResultDto getAccountResult(PmsReservationBaseParamDto pmsReservationBaseParamDto) throws Exception {
        AccountResultDto accountResultDto=new AccountResultDto();
        if(pmsReservationBaseParamDto.getIds()!=null&&pmsReservationBaseParamDto.getIds().size()>0){
            L2RIpms2AccountType queryAccountType=new L2RIpms2AccountType();
            queryAccountType.setLhotelGroupCode(pmsReservationBaseParamDto.getLhotelGroupCode());
            QueryResult<L2RIpms2AccountType> l2RIpms2AccountTypeQueryResult = commonService.findAllEQ(L2RIpms2AccountType.class, queryAccountType);
            if(l2RIpms2AccountTypeQueryResult.getResultlist()!=null&&l2RIpms2AccountTypeQueryResult.getResultlist().size()>0){
                Map<String,String> accountTypeMap=new HashMap<>();
                for(L2RIpms2AccountType l2RIpms2AccountType:l2RIpms2AccountTypeQueryResult.getResultlist()){
                    accountTypeMap.put(l2RIpms2AccountType.getPmsAccountType(),l2RIpms2AccountType.getL2RAccountType());
                }
                L2RCondition l2RCondition=new L2RCondition();
                l2RCondition.setAndConditions(new ConditionDetail[]{
                        new ConditionDetail(BaseEntity.BaseEntity_.id.toString(), CriteriaUtil.Operator.IN,pmsReservationBaseParamDto.getIds())
                });
                QueryResult<L2RIpms2Account> l2RIpms2AccountQueryResult = commonService.findAllByCondition(L2RIpms2Account.class, l2RCondition);
                if(l2RIpms2AccountQueryResult.getResultlist()!=null&&l2RIpms2AccountQueryResult.getResultlist().size()>0){
                    BigDecimal roomCharge=BigDecimal.ZERO;
                    BigDecimal otherCharge=BigDecimal.ZERO;
                    BigDecimal paid=BigDecimal.ZERO;

                    for(L2RIpms2Account account:l2RIpms2AccountQueryResult.getResultlist()){
                        switch (accountTypeMap.get(account.getArrangeCode())){
                            case L2RAccountConstant.L2RAccountType.FF:
                                 roomCharge=roomCharge.add(account.getCharge());
                                continue;
                            case L2RAccountConstant.L2RAccountType.ZF:
                                otherCharge=otherCharge.add(account.getCharge());
                                continue;
                            case L2RAccountConstant.L2RAccountType.FK:
                                paid=paid.add(account.getPay());
                                continue;
                            default:
                                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPING_ACOUNTTYPE_NOT_EXIT,"绿云账单编码："+account.getArrangeCode());
                        }
                    }
                    BigDecimal payableRoomCharge=roomCharge;
                    BigDecimal payableOtherCharge=otherCharge;
                    BigDecimal newPaid=paid;
                    if(payableOtherCharge.compareTo(paid)==-1){
                        newPaid=newPaid.subtract(payableOtherCharge);
                        payableOtherCharge=BigDecimal.ZERO;
                        payableRoomCharge=payableRoomCharge.subtract(newPaid);
                    }else {
                        payableOtherCharge=payableOtherCharge.subtract(paid);
                    }
                    accountResultDto.setRoomCharge(roomCharge);
                    accountResultDto.setOtherCharge(otherCharge);
                    accountResultDto.setPaid(paid);
                    accountResultDto.setPayableRoomCharge(payableRoomCharge);
                    accountResultDto.setPayableOteherCharge(payableOtherCharge);
                }
            }else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_MAPPING_ACOUNTTYPE_NOT_EXIT);
            }
        }
        return accountResultDto;
    }


    /**
     * 带券预定
     * @param reservationBaseDto
     * @param reservationPriceDtoList
     * @param gcOrderCouponDtoList
     * @return
     * @throws Exception
     */
    private BookWithCouponRequest reservationParamDtoToBookRequestWithCoupon(String lhotelGroupCode,
                                                                    Long hotelGroupId,
                                                                    Long hotelId,
                                                                    String rmtype,
                                                                    PmsReservationOptionDto pmsReservationOptionDto,
                                                                    ReservationBaseDto reservationBaseDto,
                                                                    List<ReservationPriceDto> reservationPriceDtoList,
                                                                    List<GcOrderCouponDto> gcOrderCouponDtoList) throws Exception {


        BookWithCouponRequest bookRequest= BookWithCouponRequest.newInstance();
        bookRequest.setHotelGroupId(hotelGroupId);
        bookRequest.setHotelId(hotelId);
        bookRequest.setArr(reservationBaseDto.getArrtime() );
        bookRequest.setDep( reservationBaseDto.getDeptime() );
        bookRequest.setAdult( reservationBaseDto.getAdult());
        bookRequest.setCardNo("");
        bookRequest.setCardType("");
        bookRequest.setCoMsg(reservationBaseDto.getCoMsg());
        //ipms2BookInfoParamDto.setChannel();
        //ipms2BookInfoParamDto.setCharge();
        //ipms2BookInfoParamDto.setDisAmount();
        bookRequest.setEmail("" );
        bookRequest.setIdNo("");
        bookRequest.setIdType("");
        bookRequest.setMarket("");
        bookRequest.setMobile( reservationBaseDto.getRsvMobile());

        bookRequest.setOtaChannel("L2R");
        bookRequest.setOtaRsvNo(reservationBaseDto.getL2RNo());
        bookRequest.setOtherRsvNo(reservationBaseDto.getTerminalNo());
        bookRequest.setSalesChannel(pmsReservationOptionDto.getSalesChannel());
        bookRequest.setPackages("");
        //ipms2BookInfoParamDto.setPaySta("");
        bookRequest.setRateCode(reservationBaseDto.getPmsRatecode());
        bookRequest.setRmtype( rmtype);
        bookRequest.setRemark(reservationBaseDto.getRemark());
        //预付订单增加提示
        if(reservationBaseDto.getResType().equals( BaseRateplanConstant.RESTYPE.PRE )) {
            bookRequest.setRemark("此订单为在线支付订单，请查看是否支付完成。" + ";" + reservationBaseDto.getRemark());
        }
        bookRequest.setRmNum( reservationBaseDto.getRoomNum());
        bookRequest.setRooms("");
        bookRequest.setRsvMan(reservationBaseDto.getRsvMan());
        bookRequest.setSex("1");
        //ipms2BookInfoParamDto.setSpecials("");
        bookRequest.setSrc(pmsReservationOptionDto.getSrc());
        bookRequest.setMarket(pmsReservationOptionDto.getMarket());
        //ipms2BookInfoParamDto.setUnionid();
        //ipms2BookInfoParamDto.setOpenid();
        //ipms2BookInfoParamDto.setWeixin();

        List<Map<String,String>> everyDayRateMapList=new ArrayList<>();
        for (ReservationPriceDto reservationPriceDto : reservationPriceDtoList) {
            Map<String,String> everyDayRateMap=new HashMap<>();
            everyDayRateMap.put("date",reservationPriceDto.getResDatetime());
            everyDayRateMap.put("realRate",String.valueOf(reservationPriceDto.getAmountPms()));
            everyDayRateMapList.add(everyDayRateMap);
        }
        bookRequest.setEveryDayRate(JacksonUtil.beanToJson(everyDayRateMapList));

        if(gcOrderCouponDtoList.size()==1){
            GcOrderCouponDto gcOrderCouponDto = gcOrderCouponDtoList.get(0);
            if(StringUtil.isNotBlank(gcOrderCouponDto.getCouponNo())) {
                bookRequest.setCouponDetailCode(gcOrderCouponDto.getCouponNo());
                bookRequest.setCouponCode(gcOrderCouponDto.getCouponCode());
                bookRequest.setCosType(gcOrderCouponDto.getCouponType());
                bookRequest.setEndDate( DateUtil.format( DateUtil.addDays(reservationBaseDto.getArr(),1L ) ,DateUtil.noSecondFormat));
                bookRequest.setStartDate(DateUtil.format(reservationBaseDto.getArr(),DateUtil.noSecondFormat));
            }
        }else {
            List<Map<String,String>> couponMapList=new ArrayList<>();
            for(GcOrderCouponDto gcOrderCouponDto:gcOrderCouponDtoList){
                Map<String,String> couponMap=new HashMap<>();
                couponMap.put("couponCode",gcOrderCouponDto.getCouponCode());
                couponMap.put("couponNo",gcOrderCouponDto.getCouponNo());
                couponMap.put("endDate",DateUtil.format( DateUtil.addDays(reservationBaseDto.getArr(),1L ) ,DateUtil.noSecondFormat));
                couponMap.put("beginDate",DateUtil.format(reservationBaseDto.getArr(),DateUtil.noSecondFormat));
            }
            bookRequest.setCouponListStr(JacksonUtil.beanToJson(couponMapList));
        }

        try{
            BaseParamDto baseParamDto=new BaseParamDto();
            baseParamDto.setLhotelGroupCode(lhotelGroupCode);
            bookRequest.setAppid(wxOfiiceialAccountsInfoFeignService.getOfficialAccountsInfo(baseParamDto.paramToMap()).getResultInfo().getAppid());
            bookRequest.setOpenid(reservationBaseDto.getOpenid());
        }
        catch (Exception e ){
            LogUtil.logger.error(ExceptionUtil.getExceptionDetail(e));
        }
        return bookRequest;
    }

    /**
     * 不带券预定
     * @param reservationBaseDto
     * @param reservationPriceDtoList
     * @return
     * @throws Exception
     */
    private BookRequest reservationParamDtoToBookRequest(String lhotelGroupCode,
                                                                   Long hotelGroupId,
                                                                   Long hotelId,
                                                                   String rmtype,
                                                                   PmsReservationOptionDto pmsReservationOptionDto,
                                                                   ReservationBaseDto reservationBaseDto,
                                                                   List<ReservationPriceDto> reservationPriceDtoList) throws Exception {
        BookRequest bookRequest= BookRequest.newInstance();
        bookRequest.setHotelGroupId(hotelGroupId);
        bookRequest.setHotelId(hotelId);
        bookRequest.setArr(reservationBaseDto.getArrtime() );
        bookRequest.setDep( reservationBaseDto.getDeptime() );
        bookRequest.setAdult( reservationBaseDto.getAdult());
        bookRequest.setCardNo("");
        bookRequest.setCardType("");
        bookRequest.setCoMsg(reservationBaseDto.getCoMsg());
        //ipms2BookInfoParamDto.setChannel();
        //ipms2BookInfoParamDto.setCharge();
        //ipms2BookInfoParamDto.setDisAmount();
        bookRequest.setEmail("" );
        bookRequest.setIdNo("");
        bookRequest.setIdType("");
        bookRequest.setMarket("");
        bookRequest.setMobile( reservationBaseDto.getRsvMobile());

        bookRequest.setOtaChannel("L2R");
        bookRequest.setOtaRsvNo(reservationBaseDto.getL2RNo());
        bookRequest.setOtherRsvNo(reservationBaseDto.getTerminalNo());
        bookRequest.setSalesChannel(pmsReservationOptionDto.getSalesChannel());
        bookRequest.setPackages("");
        //ipms2BookInfoParamDto.setPaySta("");
        bookRequest.setRateCode(reservationBaseDto.getPmsRatecode());
        bookRequest.setRmtype( rmtype);
        bookRequest.setRemark(reservationBaseDto.getRemark());
        //预付订单增加提示
        if(reservationBaseDto.getResType().equals( BaseRateplanConstant.RESTYPE.PRE )) {
            bookRequest.setRemark("此订单为在线支付订单，请查看是否支付完成。" + ";" + reservationBaseDto.getRemark());
        }
        bookRequest.setRmNum( reservationBaseDto.getRoomNum());
        bookRequest.setRooms("");
        bookRequest.setRsvMan(reservationBaseDto.getRsvMan());
        bookRequest.setSex("1");
        //ipms2BookInfoParamDto.setSpecials("");
        bookRequest.setSrc(pmsReservationOptionDto.getSrc());
        bookRequest.setMarket(pmsReservationOptionDto.getMarket());
        //ipms2BookInfoParamDto.setUnionid();
        //ipms2BookInfoParamDto.setOpenid();
        //ipms2BookInfoParamDto.setWeixin();

        List<Map<String,String>> everyDayRateMapList=new ArrayList<>();
        for (ReservationPriceDto reservationPriceDto : reservationPriceDtoList) {
            Map<String,String> everyDayRateMap=new HashMap<>();
            everyDayRateMap.put("date",reservationPriceDto.getResDatetime());
            everyDayRateMap.put("realRate",String.valueOf(reservationPriceDto.getAmountPms()));
            everyDayRateMapList.add(everyDayRateMap);
        }
        bookRequest.setEveryDayRate(JacksonUtil.beanToJson(everyDayRateMapList));
        try{
            BaseParamDto paramDto = new BaseParamDto();
            paramDto.setLhotelGroupCode(lhotelGroupCode);
            bookRequest.setAppid(wxOfiiceialAccountsInfoFeignService.getOfficialAccountsInfo(paramDto.paramToMap()).getResultInfo().getAppid());
            bookRequest.setOpenid(reservationBaseDto.getOpenid());
        }
        catch (Exception e ){
            LogUtil.logger.error(ExceptionUtil.getExceptionDetail(e));
        }
        return bookRequest;
    }

    private Integer getReservationNight(OrderInfoDto orderInfoDto) throws Exception {
        Integer nights= 0;
        if( null!= orderInfoDto){
            if(orderInfoDto.getItems().size()>0){
                for (OrderItemDto ipms2MasterInfo  :orderInfoDto.getItems()) {
                    if( "O".equals(ipms2MasterInfo.getSta())){

                        Date dateArr = new Date(Long.parseLong(ipms2MasterInfo.getArr()));
                        Date dateDep =new Date(Long.parseLong(ipms2MasterInfo.getDep()));
                        try {
                            nights+= DateUtil.getNigths( dateArr, dateDep );
                            //System.out.println(date);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }
                }
            }
        }
        return nights;
    }

    private Integer getReservationNight2(String lhotelGroupCode,String lhotelCode,String crsNo) throws Exception {
        String ffCode=SysoptionUtil.getSysOption(lhotelGroupCode,"SAVE_PAY","ffCode");
        L2RAssert.stringBlank(ffCode,"集团房费代码为空");
        L2RIpms2Account queryIAccount=new L2RIpms2Account();
        queryIAccount.setLhotelGroupCode(lhotelGroupCode);
        queryIAccount.setLhotelCode(lhotelCode);
        queryIAccount.setCrsNo(crsNo);
        QueryResult<L2RIpms2Account> accountResult = commonService.findAllEQ(L2RIpms2Account.class, queryIAccount);
        BigDecimal nights=new BigDecimal(0);
        if(accountResult.getResultlist()!=null&&accountResult.getResultlist().size()>0){
            for(L2RIpms2Account account:accountResult.getResultlist()){
                if(ffCode.equals(account.getTaCode())&&
                        account.getCharge().compareTo(new BigDecimal(0))!=0){
                    nights=nights.add(account.getQuantity());
                }
            }
        }
        return nights.intValue();
    }


    private void saveOrUpdateMasterInfo(String lhotelGroupCode,
                                                        String lhotelCode,
                                                        Long hotelGroupId,
                                                        Long hotelId,
                                                        OrderInfoDto orderInfoDto,
                                                        String l2rNo,
                                                        String crsNo) throws Exception {
        List<OrderItemDto> orderInfoItems = orderInfoDto.getItems();
        for(OrderItemDto orderInfoItem:orderInfoItems){
            L2RIpms2Master newl2RIpms2Master=ClassConverUtil.copyProperties(orderInfoItem,L2RIpms2Master.class);
            newl2RIpms2Master.setId(null);
            newl2RIpms2Master.setLhotelGroupCode(lhotelGroupCode);
            newl2RIpms2Master.setLhotelCode(lhotelCode);
            newl2RIpms2Master.setHotelGroupId(hotelGroupId);
            newl2RIpms2Master.setHotelId(hotelId);
            newl2RIpms2Master.setL2RNo(l2rNo);
            newl2RIpms2Master.setCrsNo(crsNo);
            newl2RIpms2Master.setAccnt(orderInfoItem.getId());
            newl2RIpms2Master.setArrDate(new Date(Long.parseLong(orderInfoItem.getArr())));
            newl2RIpms2Master.setDepDate(new Date(Long.parseLong(orderInfoItem.getDep())));
            newl2RIpms2Master.setNights(new BigDecimal(DateUtil.getNigths( newl2RIpms2Master.getArrDate(), newl2RIpms2Master.getDepDate() )));
            L2RIpms2Master queryMaster=new L2RIpms2Master();
            queryMaster.setLhotelGroupCode(lhotelGroupCode);
            queryMaster.setLhotelCode(lhotelCode);
            queryMaster.setMasterId(orderInfoItem.getMasterId());
            L2RIpms2Master l2RIpms2Master=commonService.findOneEQ(L2RIpms2Master.class,queryMaster);
            if(l2RIpms2Master!=null){
                Long id=l2RIpms2Master.getId();
                newl2RIpms2Master.setId(id);
                commonService.updateById(newl2RIpms2Master);
            }else {
                commonService.save(newl2RIpms2Master);
            }
        }
    }

    private L2RIpms2Master findMasterId(String lhotelGroupCode,String lhotelCode,String crsNo) throws Exception {
        L2RIpms2Master queryMaster=new L2RIpms2Master();
        queryMaster.setLhotelGroupCode(lhotelGroupCode);
        queryMaster.setLhotelCode(lhotelCode);
        queryMaster.setCrsNo(crsNo);
        QueryResult<L2RIpms2Master> l2RIpms2MasterQueryResult= commonService.findAllEQ(L2RIpms2Master.class, queryMaster);
        if(l2RIpms2MasterQueryResult.getResultlist()!=null&&l2RIpms2MasterQueryResult.getResultlist().size()>0){
            return l2RIpms2MasterQueryResult.getResultlist().get(0);
        }else {
            return null;
        }
    }

    private void saveGcBillAccount(String lhotelGroupCode,
                                     String lhotelCode,
                                   String crsNo,
                                   String l2rNo) throws Exception {
        L2RIpms2Master l2RIpms2Master = this.findMasterId(lhotelGroupCode, lhotelCode, crsNo);
        if(l2RIpms2Master!=null){
            if(l2RIpms2Master.getMasterId()!=null){
                ListBillInfoRequest req = ListBillInfoRequest.newInstance();
                req.setHotelGroupId(l2RIpms2Master.getHotelGroupId());
                req.setHotelId(l2RIpms2Master.getHotelId());
                req.setMasterId(l2RIpms2Master.getMasterId());
                ListBillInfoResponse resp = GcPmsUtil.getGcClient(lhotelGroupCode).execute(req);
                if(resp.getResultCode()<0){
                    throw new SoundwaveException(SoundwaveSysExceptionEnum.GCPMS_ACCOUNT_ERROR,resp.getResultMsg());
                }else {
                    L2RIpms2Account queryIAccount=new L2RIpms2Account();
                    queryIAccount.setLhotelGroupCode(lhotelGroupCode);
                    queryIAccount.setLhotelCode(lhotelCode);
                    queryIAccount.setCrsNo(crsNo);
                    QueryResult<L2RIpms2Account> oldAccountResult = commonService.findAllEQ(L2RIpms2Account.class, queryIAccount);
                    List<L2RIpms2Account> l2RIpms2AccountList = ClassConverUtil.copyPropertiesList(resp.getResult(), L2RIpms2Account.class);
                    if(oldAccountResult.getResultlist()!=null){
                        Iterator<L2RIpms2Account> accountIterator = l2RIpms2AccountList.iterator();
                        while (accountIterator.hasNext()){
                            L2RIpms2Account account = accountIterator.next();
                            for(L2RIpms2Account oldAccount:oldAccountResult.getResultlist()){
                                if(oldAccount.getAccountId().equals(account.getId())){
                                    accountIterator.remove();
                                }
                            }
                        }
                    }
                    for(L2RIpms2Account account:l2RIpms2AccountList){
                        account.setAccountId(account.getId());
                        account.setId(null);
                        account.setLhotelGroupCode(lhotelGroupCode);
                        account.setLhotelCode(lhotelCode);
                        account.setCrsNo(crsNo);
                        account.setL2RNo(l2rNo);
                    }
                    commonService.saveList(l2RIpms2AccountList);
                }
            }
        }
    }

    @Override
    String memberCardPrepay(MemeberCardPayInsideParamDto memeberCardPayInsideParamDto) throws Exception {
        String lhotelGroupCode=memeberCardPayInsideParamDto.getLhotelGroupCode();
        String lhotelCode=memeberCardPayInsideParamDto.getLhotelCode();
        String orderNo=memeberCardPayInsideParamDto.getOrderNo();
        String memberNo=memeberCardPayInsideParamDto.getMemberNo();
        String notifyUrl=memeberCardPayInsideParamDto.getNotifyUrl();
        String taCode=memeberCardPayInsideParamDto.getTaCode();
        BigDecimal totalFee=memeberCardPayInsideParamDto.getTotalFee();
        Lock lock = membercardPrepayIdLock.obtain("prepayId");
        L2RIpms2Reservation queryReser=new L2RIpms2Reservation();
        queryReser.setLhotelGroupCode(lhotelGroupCode);
        queryReser.setLhotelCode(lhotelCode);
        queryReser.setL2RNo(orderNo);
        L2RIpms2Reservation l2RIpms2Reservation=commonService.findOneEQ(L2RIpms2Reservation.class,queryReser);
        Optional.ofNullable(l2RIpms2Reservation).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_NOT_EXIT));
        String crsNo=Optional.ofNullable(l2RIpms2Reservation.getCrsNo()).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_SAVE_ERROR));
        if(lock.tryLock(5, TimeUnit.SECONDS)){
            try {
                L2RIpms2CardPay query=new L2RIpms2CardPay();
                query.setOrderNo(orderNo);
                QueryResult<L2RIpms2CardPay> l2RIpms2CardPayQueryResult=commonService.findAllEQ(L2RIpms2CardPay.class,query);
                //检查是否存在预下单且金额一致记录，如一致则返回之前已入库的预下单号
                String prepayId=Optional.ofNullable(l2RIpms2CardPayQueryResult.getResultlist()).map(
                        TryExceptionUtil.of(
                                list->{
                                    if(list.stream().filter(event-> totalFee.compareTo(event.getTotalFee())!=0).count()>0){
                                        throw new SoundwaveException(SoundwaveSysExceptionEnum.MEMBER_CARD_PAY_FEE_IS_NOT_MATCH);
                                    }
                                    return list.stream().filter(event-> totalFee.compareTo(event.getTotalFee())==0).findAny().map(
                                            event->event.getPrepayId()).orElse(null);
                                }
                        )
                ).orElse(null);
                if(StringUtil.isBlank(prepayId)){
                    L2RIpms2Member queryL2RMemeber=new L2RIpms2Member();
                    queryL2RMemeber.setLhotelGroupCode(lhotelGroupCode);
                    queryL2RMemeber.setL2RMemberNo(memberNo);
                    L2RIpms2Member l2RIpms2Member=commonService.findOneEQ(L2RIpms2Member.class,queryL2RMemeber);
                    Optional.ofNullable(l2RIpms2Member).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.PMSMEMBER_NOT_EXIT,memberNo));
                    GetCardBalanceInfoRequest request = GetCardBalanceInfoRequest.newInstance();
                    request.setHotelGroupId(1L);
                    request.setCardId(l2RIpms2Member.getCardId().toString());
                    request.setCardNo("");
                    request.setTag("");
                    GetCardBalanceInfoResponse resp = GcPmsUtil.getGcClient(lhotelGroupCode).execute(request);
                    if(Objects.equals(0,resp.getResultCode())){
                        if(totalFee.compareTo(new BigDecimal(resp.getResult().getAccountBalanceUse()))>0){
                            throw new SoundwaveException(SoundwaveSysExceptionEnum.GC_PMS_CARD_ACCOUNT_LESS,resp.getResult().getAccountBalanceUse());
                        }
                    }else {
                        throw new SoundwaveException(SoundwaveSysExceptionEnum.GC_PMS_GET_CARD_ACCOUNT_ERROR,resp.getResultMsg());
                    }
                    SysNoBaseParamDto sysNoBaseParamDto=new SysNoBaseParamDto();
                    sysNoBaseParamDto.setNoType("memberCardPay");
                    prepayId=sysNoFeignService.getSysNo(sysNoBaseParamDto.paramToMap()).getResultInfo();
                    L2RIpms2CardPay l2RIpms2CardPay=new L2RIpms2CardPay();
                    l2RIpms2CardPay.setLhotelGroupCode(lhotelGroupCode);
                    l2RIpms2CardPay.setLhotelCode(lhotelCode);
                    l2RIpms2CardPay.setOrderNo(orderNo);
                    l2RIpms2CardPay.setCardId(l2RIpms2Member.getCardId().toString());
                    l2RIpms2CardPay.setCardNo(l2RIpms2Member.getCardNo());
                    l2RIpms2CardPay.setL2RMemberNo(memberNo);
                    l2RIpms2CardPay.setNotifyUrl(notifyUrl);
                    l2RIpms2CardPay.setPrepayId(prepayId);
                    l2RIpms2CardPay.setTotalFee(totalFee);
                    l2RIpms2CardPay.setTaCode(taCode);
                    l2RIpms2CardPay.setGoodName(memeberCardPayInsideParamDto.getGoodName());
                    l2RIpms2CardPay.setCrsNo(crsNo);
                    commonService.save(l2RIpms2CardPay);
                }
                return prepayId;
            }finally {
                lock.unlock();
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.MEMBER_CARD_PREPAY_ERROR);
        }
    }

    @Override
    MemberCardPayDto memberCardPay(MemeberCardPayApiParamDto memeberCardPayApiParamDto) throws Exception {
        String lhotelGroupCode=memeberCardPayApiParamDto.getLhotelGroupCode();
        String prepayId=memeberCardPayApiParamDto.getL2rPrepayId();
        String passwordReal=memeberCardPayApiParamDto.getPasswordReal();
        Lock lock=membercardPayLock.obtain("memberCardPay");
        if(lock.tryLock(5, TimeUnit.SECONDS)){
            try {
                L2RIpms2CardPay queryL2rCardPay=new L2RIpms2CardPay();
                queryL2rCardPay.setLhotelGroupCode(lhotelGroupCode);
                queryL2rCardPay.setPrepayId(prepayId);
                L2RIpms2CardPay l2RIpms2CardPay=commonService.findOneEQ(L2RIpms2CardPay.class,queryL2rCardPay);
                String taNo=Optional.ofNullable(l2RIpms2CardPay).map(
                        TryExceptionUtil.of(event->{
                            return this.gcPmsCardPay(event,passwordReal);
                        })
                ).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.CARDPAY_PREPAY_DETAIL_IS_NOT_EXIT));
                l2RIpms2CardPay.setRealPayFee(l2RIpms2CardPay.getTotalFee());
                l2RIpms2CardPay.setCardTaNo(taNo);
                l2RIpms2CardPay.setIsSuccess(DefaultValue.T);
                commonService.merge(l2RIpms2CardPay);
                MemberCardPayDto memberCardPayDto=new MemberCardPayDto();
                memberCardPayDto.setTaNo(taNo);
                memberCardPayDto.setAmount(l2RIpms2CardPay.getTotalFee());
                return memberCardPayDto;
            }finally {
                lock.unlock();
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.MEMBER_CARD_PAY_ERROR);
        }
    }

    private String gcPmsCardPay(L2RIpms2CardPay l2RIpms2CardPay,String password) throws Exception {
        SysNoBaseParamDto sysNoBaseParamDto=new SysNoBaseParamDto();
        sysNoBaseParamDto.setNoType("cardPayNo");
        String taNo = sysNoFeignService.getSysNo(sysNoBaseParamDto.paramToMap()).getResultInfo();
        SaveMemberCardPayRequest req = SaveMemberCardPayRequest.newInstance();
        req.setHotelGroupId(1L);
        req.setCardId(l2RIpms2CardPay.getCardId());
        req.setCardNo(l2RIpms2CardPay.getCardNo());
        req.setCrsNo(l2RIpms2CardPay.getCrsNo());
        req.setTaCode(l2RIpms2CardPay.getTaCode());
        req.setTaNo(taNo);
        req.setTaRemark("联房储值卡支付");
        req.setPassword(password);
        req.setMoney(l2RIpms2CardPay.getTotalFee().toString());
        PmsResponse resp =  GcPmsUtil.getGcClient(l2RIpms2CardPay.getLhotelGroupCode()).execute(req);
        if(!Objects.equals(resp.getResultCode(),0)){
            throw new SoundwaveException(SoundwaveSysExceptionEnum.MEMBER_CARD_PAY_ERROR,resp.getResultMsg());
        }
        return taNo;
    }
}
